﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using ParsecParser;
using ParsecParser.Communication;
using ParsecParser.Data;
using ParsecParser.Display;
using ParsecParser.Helpers;
using WMPLib;

namespace ParsecClient.Classes
{
    public static class ParsecClientHelpers
    {
        //public static Color OrangeSolid = (Color)ColorConverter.ConvertFromString("#FFfbe7c8");
        //public static Color RedSolid = (Color)ColorConverter.ConvertFromString("#FFfbc8c8");
        //public static Color BlueSolid = (Color)ColorConverter.ConvertFromString("#FFc8e7fb");
        //public static Color PurpleSolid = (Color)ColorConverter.ConvertFromString("#FFeac8e7");
        //public static Color GraySolid = (Color)ColorConverter.ConvertFromString("#FFEEEEEE");
        public static Color OrangeSolid = (Color)ColorConverter.ConvertFromString("#FFFF8800");
        public static Color RedSolid = (Color)ColorConverter.ConvertFromString("#FFFF4444");
        public static Color BlueSolid = (Color)ColorConverter.ConvertFromString("#FF66CCFF");
        public static Color PurpleSolid = (Color)ColorConverter.ConvertFromString("#FFd2a7ed");
        public static Color GraySolid = (Color)ColorConverter.ConvertFromString("#FFEEEEEE");
        public static Color OrangeTransparent = (Color)ColorConverter.ConvertFromString("#33FF9900");
        public static Color RedTransparent = (Color)ColorConverter.ConvertFromString("#33FF0000");
        public static Color BlueTransparent = (Color)ColorConverter.ConvertFromString("#330099FF");
        public static Color PurpleTransparent = (Color)ColorConverter.ConvertFromString("#33AA0099");
        public static Color GrayTransparent = (Color)ColorConverter.ConvertFromString("#33999999");
        public static Color MainLabelColor = (Color)ColorConverter.ConvertFromString("#FF50504d");
        public static Color LightMainLabelColor = (Color)ColorConverter.ConvertFromString("#9950504d");
        public static SolidColorBrush WhiteBackground = new SolidColorBrush(System.Windows.Media.Colors.White);
        public static SolidColorBrush BlackBackground = new SolidColorBrush(System.Windows.Media.Colors.Black);
        public static SolidColorBrush TransparentBackground = new SolidColorBrush(System.Windows.Media.Colors.Transparent);

        public static SolidColorBrush OrangeTransparentBrush = new SolidColorBrush(OrangeTransparent);
        public static SolidColorBrush RedTransparentBrush = new SolidColorBrush(RedTransparent);
        public static SolidColorBrush BlueTransparentBrush = new SolidColorBrush(BlueTransparent);
        public static SolidColorBrush PurpleTransparentBrush = new SolidColorBrush(PurpleTransparent);
        public static SolidColorBrush GrayTransparentBrush = new SolidColorBrush(GrayTransparent);
        public static SolidColorBrush MainLabelColorBrush = new SolidColorBrush(MainLabelColor);
        public static SolidColorBrush LightMainLabelColorBrush = new SolidColorBrush(LightMainLabelColor);


        public static SolidColorBrush OrangeSolidBrush = new SolidColorBrush(OrangeSolid);
        public static SolidColorBrush RedSolidBrush = new SolidColorBrush(RedSolid);
        public static SolidColorBrush BlueSolidBrush = new SolidColorBrush(BlueSolid);
        public static SolidColorBrush PurpleSolidBrush = new SolidColorBrush(PurpleSolid);
        public static SolidColorBrush GraySolidBrush = new SolidColorBrush(GraySolid);
        public static SolidColorBrush GetDamageColor(this CombatLogEntity damageType)
        {
            if (damageType == null)
                return null;
            else
            {
                switch (damageType.EntityId)
                {
                    case CombatLogConstants.DamageTypes.Elemental :
                        return OrangeTransparentBrush;
                    case CombatLogConstants.DamageTypes.Energy:
                        return BlueTransparentBrush;
                    case CombatLogConstants.DamageTypes.Internal:
                        return RedTransparentBrush;
                    case CombatLogConstants.DamageTypes.Kinetic:
                        return PurpleTransparentBrush;
                    default:
                        return null;
                }
            }
        }
        public static SolidColorBrush GetDamageForegroundColor(this CombatLogEntity damageType)
        {
            if (damageType == null)
                return null;
            else
            {
                switch (damageType.EntityId)
                {
                    case CombatLogConstants.DamageTypes.Elemental:
                        return OrangeSolidBrush;
                    case CombatLogConstants.DamageTypes.Energy:
                        return BlueSolidBrush;
                    case CombatLogConstants.DamageTypes.Internal:
                        return RedSolidBrush;
                    case CombatLogConstants.DamageTypes.Kinetic:
                        return PurpleSolidBrush;
                    default:
                        return GraySolidBrush;
                }
            }
        }
        public static string Capitalize(this string word)
        {
            if (string.IsNullOrEmpty(word))
                return word;
            return word.ToCharArray()[0].ToString().ToUpper() + word.Substring(1);
        }
        private static System.Text.RegularExpressions.Regex PascalReplacementRegex = new System.Text.RegularExpressions.Regex("([A-Z])", System.Text.RegularExpressions.RegexOptions.Compiled);
        public static string GetPascalCaseAsWords(this string s)
        {
            return PascalReplacementRegex.Replace(s, " $1");
        }
        public static void PlaySound(this TimerSound s)
        {
            //System.Audio.Volume = 100;
            switch (s)
            {
                case TimerSound.ArtooScream:
                    PlaySound("R2_Scream.wav");
                    break;
                case TimerSound.ArtooWarning:
                    PlaySound("R2_Warning.wav");
                    break;
                case TimerSound.ChewbaccaArrrrg:
                    PlaySound("Chewy_Arg.wav");
                    break;
                case TimerSound.ChewbaccaLaugh:
                    PlaySound("Chewy_Laugh.wav");
                    break;
                case TimerSound.DontGetCocky:
                    PlaySound("Han_DontGetCocky.wav");
                    break;
                case TimerSound.IHaveYouNow:
                    PlaySound("Vader_IHaveYouNow.wav");
                    break;
                case TimerSound.Impressive:
                    PlaySound("Vader_Impressive.wav");
                    break;
                case TimerSound.ItsATrap:
                    PlaySound("Ackbar_Trap.wav");
                    break;
                case TimerSound.PickUpYourVisualScanning:
                    PlaySound("RedLdr_VisualScan.wav");
                    break;
                case TimerSound.SmoothLando:
                    PlaySound("Lando_Hello.wav");
                    break;
                case TimerSound.ThatGotHim:
                    PlaySound("Wedge_ThatGotHim.wav");
                    break;
                case TimerSound.ThatsNoMoon:
                    PlaySound("Kenobi_NoMoon.wav");
                    break;
                case TimerSound.UseTheForce:
                    PlaySound("Kenobi_UseForce.wav");
                    break;
                case TimerSound.Utini:
                    PlaySound("Jawa_Utini.wav");
                    break;
                case TimerSound.VadersBreath:
                    PlaySound("Vader_Breathing.wav");
                    break;
                case TimerSound.YodaLaugh:
                    PlaySound("Yoda_Laugh.wav");
                    break;
                case TimerSound.DingAirline:
                    PlaySound("Ding_Airline.wav");
                    break;
                case TimerSound.DingCashMoney:
                    PlaySound("Ding_CashMoney.wav");
                    break;
                case TimerSound.DingCorrectAnswer:
                    PlaySound("Ding_CorrectAnswer.wav");
                    break;
                case TimerSound.DingShiny:
                    PlaySound("Ding_Shiny.wav");
                    break;
                case TimerSound.WarningBuzzer:
                    PlaySound("WarningBuzzer.wav");
                    break;

            }
        }
        public static void PlaySound(string filename)
        {
            System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
            using (System.IO.Stream str = a.GetManifestResourceStream("ParsecClient.Audio." + filename))
            {
                if (str != null)
                {
                    using (System.Media.SoundPlayer thisSound = new System.Media.SoundPlayer(str))
                    {
                        thisSound.Play();
                    }
                }
            }
        }
        private static System.Speech.Synthesis.SpeechSynthesizer SpeechSynth;
        public static void PlayTextToSpeech(string text)
        {
            if (!string.IsNullOrEmpty(text))
            {
                if (SpeechSynth == null)
                {
                    SpeechSynth = new System.Speech.Synthesis.SpeechSynthesizer();
                    SpeechSynth.SetOutputToDefaultAudioDevice();
                }
                SpeechSynth.Rate = 2;
                SpeechSynth.SpeakAsyncCancelAll();
                SpeechSynth.SpeakAsync(text);
            }
        }
        public static WMPLib.WindowsMediaPlayer WPlayer;
        public static void PlayCustomSound(string filePath)
        {
            if (!string.IsNullOrEmpty(filePath) && System.IO.File.Exists(filePath))
            {
                if (System.IO.Path.GetExtension(filePath).NullToEmpty().ToUpper() == "WAV")
                {
                    using (System.Media.SoundPlayer thisSound = new System.Media.SoundPlayer(filePath))
                    {
                        thisSound.Play();
                    }
                }
                else
                {
                    if (WPlayer == null)
                        WPlayer = new WMPLib.WindowsMediaPlayer();
                    WPlayer.URL = filePath;
                    WPlayer.controls.play();
                }
            }
        }
        public static int FindOptimalPollRate(DateTime lastFileReadDate, int currentPollRate, int currentReadRate, double aggressiveness, int gracePeriod, int additionalCustomDelay)
        {
            if (aggressiveness < 0)
                aggressiveness = 0;
            else if (aggressiveness > 1)
                aggressiveness = 1;
            DateTime nextScheduledFileRead = lastFileReadDate.AddMilliseconds(currentReadRate);
            int optimalMsTillNextPoll = Convert.ToInt32(nextScheduledFileRead.Subtract(DateTime.Now).TotalMilliseconds) + additionalCustomDelay;
            if (optimalMsTillNextPoll < (currentPollRate - gracePeriod)) //give 100ms grace on min poll rate
            {
                //less than min poll rate
                //if min poll rate puts the update halfway to next read just skip
                int acceptableDelay = (optimalMsTillNextPoll - gracePeriod) + Convert.ToInt32(aggressiveness * currentReadRate);
                if (currentPollRate < acceptableDelay)
                    return currentPollRate;
                else if ((optimalMsTillNextPoll + currentReadRate) >= (currentPollRate - gracePeriod))
                {
                    //skip next read
                    return optimalMsTillNextPoll + currentReadRate;
                }
                else
                    return currentPollRate;
            }
            if (optimalMsTillNextPoll > currentPollRate * 2)
            {
                return currentPollRate; //rate was more than 2 reads so give up
            }
            return optimalMsTillNextPoll;
        }

    }
}
